//#define __FORCE_TRACE__
//#define __FORCE_DEBUG__
//#define __FORCE_INFO__
#define THIS_FILE "ia\fn_sniper.sqf"
#include <tmf_constants.h>
#include <tmf_macros.h>

TRACE_1("Start",_this);
TMFPROFILERSTART;

private ["_grp", "_pos","_radius","_debug","_units","_list","_wp","_bldgpos","_pos_details"];
DEFAULT_PARAM(_grp,0,grpNull);
DEFAULT_PARAM(_pos,1,[]);
DEFAULT_PARAM(_radius,2,100);
DEFAULT_PARAM(_debug,3,false);

// We delay the execution to let the framework initialize.
if (isNil "TMF_INITIALIZED") then {
	waituntil {sleep 0.345; !isNil "TMF_INITIALIZED"};
	sleep (0.5 + random(3));
};

if (AND_ALSO((!isnull _grp),IS_OBJECT(_grp))) then {
	_grp = group _grp;
};
if (AND_ALSO((!isnull _grp),IS_GROUP(_grp))) then {
	if (!AND_ALSO(IS_ARRAY(_pos),(count _pos == 3))) then {
		_pos = getPos (leader _grp);
	};

	_grp setBehaviour "AWARE";

	_units = (units _grp);
	DEBUG_1("Beginning",ARR_3(_grp,_pos,_units));
	if ((count _pos != 3) || {(([0,0,0] distance _pos) < 1)} || {count _units <= 0}) exitWith {
		ERROR("Position not set or empty group");
	};

	_grp allowFleeing 0;
	_grp setBehaviour "STEALTH";
	_grp setCombatMode "RED";
	
	// We remove the radios so the ASR AI doesn't communicate what snipers know about players
	{ _x unlinkItem "ItemRadio";
	} foreach (units _grp);

	_bldgpos = [_pos, _radius] call FFUNC(buildingSniperPosBuilder);
	
	for "_i" from 0 to ((count _units) min (count _bldgpos)) - 1 do {
		_idx = _bldgpos call FFUNC(arrayRandomIndex);
		if (_idx >= 0) then {
			_pos_details = _bldgpos select _idx;
			_bldgpos set [_idx, "XxDeLxX"];
			_bldgpos = _bldgpos - ["XxDeLxX"];
			(_units select _i) setPosATL (_pos_details select 0);
			(_units select _i) setUnitPosWeak (_pos_details select 2);
			(_units select _i) call FFUNC(stuckUnit);
			DEBUG_1("Sniper set",ARR_3(_grp,_units select _i,_pos_details));
		};
	};
	
	If (_debug) then {
		_units spawn {
			private ["_group","_units","_marker","_marker_name"];
			sleep 8;
			_units = _this;
			{
				_marker_name = Format["Unit%1",str(_x)];
				_marker = createMarker[_marker_name,[(getPos _x) select 0,(getPos _x) select 1]];
				_marker setMarkerShape "ICON";
				_marker_name setMarkerType "loc_Stack";
				_marker_name setMarkerColor "ColorRed";
			} foreach _units;
		};
	};
	
	_grp spawn {
		private ["_grp","_players","_sniper","_enemy","_near","_mags","_initial"];
		_grp = _this;
		{
			_x setVariable ["mags",magazines _x];
			TRACE_2("Sniper set mags",_x,_x getVariable "mags");
		} foreach (units _grp);
		sleep 10.123;
		while {!(isNull _grp)} do {
			call d_fnc_mpcheck;
			_players = if (isMultiPlayer) then { playableUnits } else { [player] };
			{
				_sniper = _x;
				if (!isNull _sniper && {alive _sniper}) then {
					_mags = +(_sniper getVariable ["mags",[]]);
					{ 
						if ((_mags find _x) >= 0) then {
							_mags set [(_mags find _x), "XXdelXX"];
							_mags = _mags - ["XXdelXX"];
						};
					} foreach magazines _sniper;
					if (count _mags > 0) then {
						TRACE_2("Missing magazines",_sniper,_x);
						{ _sniper addMagazine _x;
						} foreach _mags;
					};
					_enemy = objNull;
					_near = [];
					{
						if (!(_x getVariable["xr_pluncon",false]) && {((vehicle _x) distance _sniper) <= 500} && {!((vehicle _x) isKindOf "Air")}) then {
							_near set [count _near, _x];
						};
					} foreach _players;
					if (count _near > 0) then {
						_enemy = _near select (_near call FFUNC(arrayRandomIndex));
						if (!isNull _enemy && {(_sniper knowsAbout _enemy <= 2.0)} && {!(lineIntersects [getPosATL _sniper, getPosATL _enemy, vehicle _sniper, vehicle _enemy])} && {!((vehicle _enemy) isKindOf "Air")}) then {
							TRACE_1("Found new enemy",_enemy);
							// Reveal is dependent on distance but should be between 1.5 and 3
							_sniper reveal [_enemy, ((3 * (200 / ((vehicle _enemy) distance _sniper))) min 3)];
						};
					};
				};
				sleep 2.321;
			} forEach (units _grp);
			sleep 25.123;
		};
	};
} else {
	ERROR("Group is null");
};
TRACE("End");
TMFPROFILERSTOP;